<?php

/**
 * Class used to display and validate form 
 */
class Form {

    /**
     * Form inputs that will be displayed and validated
     * @var Array
     */
    private $formInputs;

    /**
     * Form redirect address
     * @var String
     */
    private $address;

    /**
     * Form send method type - either POST or GET
     * @var type 
     */
    private $method;

    /**
     * Enctype of form data
     * @var type 
     */
    private $enctype;

    /**
     * Default constructor
     * @param string $address
     * @param string $method
     */
    public function __construct($address = null, $method = 'POST') {
        if ($address == null)
            $address = $_SERVER['PHP_SELF'] . '?' . $_SERVER['QUERY_STRING'];
        $this->address = $address;
        $this->method = $method;
    }

    /**
     * Adds input to form on next position
     * @param FormInput $key
     * @throws Exception 
     */
    public function addInput($key) {
        if (!$key instanceof FormInput)
            throw new Exception("You can only add to form inputs");
        if ($key->inputType == 'file')
            $this->enctype = 'enctype="multipart/form-data"';
        $this->formInputs[$key->name] = $key;
    }

    /**
     * Adds submit button with given value as it text and with given name
     * @param string $name
     * @param string $value 
     */
    public function addSubmit($name, $value) {
        $this->addInput(new FormInput($name, false, "submit", null, '', array("value" => $value)));
    }

    /**
     * Renders form and returns html for it
     * @return string 
     */
    public function renderForm() {
        $html = "<form action='{$this->address}' method='{$this->method}' {$this->enctype}>\n";
        foreach ($this->formInputs as $input)
            $html .= $input->renderFormInput() . "\n";
        $html .= "</form>\n";
        return $html;
    }

    /**
     * Validates form data
     * @param Array $data
     * @return boolean|Array
     */
    public function validateData($data) {
        $errors = array();
        foreach ($this->formInputs as $name => $input) {
            if ($input->required && !array_key_exists($name, $data)) {
                $errors[] = "Pole $name nie zostało wypełnione, chociaż jego zawartość jest wymagana.<br/>\n";
            }
        }
        foreach ($data as $key => $value) {
            $inputErrors = $this->formInputs["$key"]->validateData($value);
            if (is_array($inputErrors))
                foreach ($inputErrors as $error)
                    $errors[] = $error;
        }
        if (count($errors) > 0)
            return $errors;
        return true;
    }

}

?>
